<script setup>
import { ref, onMounted, computed } from 'vue'
import { ElMessage } from 'element-plus'
import { queryConsumePageApi } from '@/api/consume'
import { merchantTypes, ensureMerchantTypes } from '@/shared/merchantTypes'
import { departments, grades, ensureSchoolOptions } from '@/shared/schoolOptions'

// 分页相关
const total = ref(0)
const background = ref(true)

// 当前页数据与展示数据（过滤后）
const pageRows = ref([])
const consumeList = ref([])

// 搜索表单
const searchForm = ref({
  consumeRange: [],
  userKeyword: '',
  merchantType: '',
  merchantName: '',
  minAmount: null,
  maxAmount: null,
  abnormalStatus: 'all',
  importBatch: '',
  page: 1,
  pageSize: 10
})
// 导出筛选（学院/年级，可选；商户类型复用 searchForm.merchantType）
const exportFilters = ref({ department: '', grade: '' })

// 商户类型选项（全局共享）
const availableMerchantTypes = merchantTypes

// 支付方式文本
const paymentText = (val) => {
  if (val === 0 || val === '0') return '智能卡'
  if (val === 1 || val === '1') return '扫码'
  return '未知'
}

// 时间格式化/解析
const pad = (n) => (n < 10 ? '0' + n : '' + n)
const formatTime = (t) => {
  if (!t) return ''
  const d = typeof t === 'string' || typeof t === 'number' ? new Date(String(t).replace(/-/g, '/')) : t
  if (isNaN(d.getTime())) return String(t)
  const Y = d.getFullYear()
  const M = pad(d.getMonth() + 1)
  const D = pad(d.getDate())
  const h = pad(d.getHours())
  const m = pad(d.getMinutes())
  const s = pad(d.getSeconds())
  return `${Y}-${M}-${D} ${h}:${m}:${s}`
}
const parseTimeToMillis = (t) => {
  if (!t) return NaN
  if (typeof t === 'string') {
    const d = new Date(t.replace(/-/g, '/'))
    return d.getTime()
  }
  const d = new Date(t)
  return d.getTime()
}

// 金额格式化与大额判断
const formatAmount = (v) => {
  const num = Number(v)
  if (Number.isNaN(num)) return `¥${v}`
  return `¥${num.toFixed(2)}`
}
const isLargeAmount = (v) => {
  const num = Number(v)
  return !Number.isNaN(num) && num > 500
}


// 查询接口（服务端分页：page/pageSize）并应用过滤
const fetchData = async () => {
  const result = await queryConsumePageApi(searchForm.value)
  if (result && result.code) {
    const rows = Array.isArray(result.data?.rows) ? result.data.rows : []
    total.value = Number(result.data?.total || rows.length)
    pageRows.value = rows
    // 直接展示后端返回的数据
    consumeList.value = rows
  } else {
    ElMessage.error(result?.msg || '消费记录获取失败')
  }
}

// 事件处理
const onSearch = () => {
  searchForm.value.page = 1
  fetchData()
}
const clearFilters = () => {
  const ps = searchForm.value.pageSize
  searchForm.value = {
    consumeRange: [],
    userKeyword: '',
    merchantType: '',
    merchantName: '',
    minAmount: null,
    maxAmount: null,
    paymentTypes: ['0', '1'],
    abnormalStatus: 'all',
    importBatch: '',
    page: 1,
    pageSize: ps
  }
  fetchData()
}
const handleSizeChange = () => {
  fetchData()
}
const handleCurrentChange = () => {
  fetchData()
}

const token = ref('')
const exporting = ref(false)
const setToken = () => {
  const user = JSON.parse(localStorage.getItem('user'))
  if (user && user.token) {
    token.value = user.token
  }
}
const handleImportSuccess = (response) => {
  if (response && response.code) {
    ElMessage.success('导入成功')
    searchForm.value.page = 1
    fetchData()
  } else {
    ElMessage.error(response?.msg || '导入失败')
  }
}
// 导出为 Excel（POST JSON，后端直接以附件响应）
const exportExcel = async () => {
  if (exporting.value) return
  exporting.value = true
   try {
     const body = {
       department: exportFilters.value.department || '',
       grade: exportFilters.value.grade || '',
       merchantType: searchForm.value.merchantType || ''
     }
     const resp = await fetch('/api/consumptionRecord/excel', {
       method: 'POST',
       headers: {
         'Content-Type': 'application/json',
         ...(token.value ? { token: token.value } : {})
       },
       body: JSON.stringify(body)
     })
     if (!resp.ok) {
       throw new Error(`导出失败：${resp.status}`)
     }
     const cd = resp.headers.get('Content-Disposition') || resp.headers.get('content-disposition') || ''
     let filename = '消费数据报表.xlsx'
     const matchStar = cd.match(/filename\*=UTF-8''([^;\n]+)/)
     const matchSimple = cd.match(/filename="?([^";\n]+)"?/)
     if (matchStar && matchStar[1]) {
       try { filename = decodeURIComponent(matchStar[1]) } catch {}
     } else if (matchSimple && matchSimple[1]) {
       filename = matchSimple[1]
     }
     const blob = await resp.blob()
     const url = URL.createObjectURL(blob)
     const a = document.createElement('a')
     a.href = url
     a.download = filename
     document.body.appendChild(a)
     a.click()
     a.remove()
     URL.revokeObjectURL(url)
     ElMessage.success('导出成功，正在下载...')
   } catch (e) {
     ElMessage.error(e?.message || '导出异常')
  } finally {
    exporting.value = false
   }
 }
const beforeImportUpload = (file) => {
  const allowedTypes = ['text/csv', 'application/vnd.ms-excel', 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet']
  const isTypeOk = allowedTypes.includes(file.type) || /\.(csv|xls|xlsx)$/i.test(file.name)
  if (!isTypeOk) {
    ElMessage.error('仅支持CSV或Excel文件')
    return false
  }
  // 已移除文件大小上限（不再限制20MB）
  return true
}

onMounted(() => {
  ensureMerchantTypes()
  ensureSchoolOptions()
  fetchData()
  setToken()
})
</script>

<template>
  <h1>消费记录展示</h1>
  <!-- 搜索栏 -->
  <div class="container">
    <el-form :inline="true" :model="searchForm" class="search-form" @keyup.enter="onSearch">
      <el-form-item label="时间范围">
        <el-date-picker
          v-model="searchForm.consumeRange"
          type="datetimerange"
          range-separator="到"
          start-placeholder="开始时间"
          end-placeholder="结束时间"
          value-format="YYYY-MM-DD"
        />
      </el-form-item>

      <el-form-item label="用户名/学号">
        <el-input v-model="searchForm.userKeyword" placeholder="输入姓名或学号" clearable @keyup.enter="onSearch" />
      </el-form-item>

      <el-form-item label="商户类型">
        <el-select v-model="searchForm.merchantType" placeholder="请选择类型" clearable @change="onSearch" style="width: 150px">
          <el-option v-for="t in availableMerchantTypes" :key="t" :label="t" :value="t" />
        </el-select>
      </el-form-item>

      <el-form-item label="商户名称">
        <el-input v-model="searchForm.merchantName" placeholder="商户名称" clearable @keyup.enter="onSearch" />
      </el-form-item>

      <el-form-item label="金额最小">
        <el-input-number v-model="searchForm.minAmount" :precision="2" :step="1" :controls="false" placeholder="最小金额" />
      </el-form-item>
      <el-form-item label="金额最大">
        <el-input-number v-model="searchForm.maxAmount" :precision="2" :step="1" :controls="false" placeholder="最大金额" />
      </el-form-item>

      <el-form-item label="异常状态">
        <el-radio-group v-model="searchForm.abnormalStatus"  @change="onSearch">
          <el-radio label="all">全部</el-radio>
          <el-radio label="normal">正常交易</el-radio>
          <el-radio label="abnormal">异常交易</el-radio>
        </el-radio-group>
      </el-form-item>

      <el-form-item label="导出学院">
        <el-select v-model="exportFilters.department" placeholder="选择学院" clearable style="width: 220px" filterable>
          <el-option v-for="dep in departments" :key="dep" :label="dep" :value="dep" />
        </el-select>
      </el-form-item>
      <el-form-item label="导出年级">
        <el-select v-model="exportFilters.grade" placeholder="选择年级" clearable style="width: 160px">
          <el-option v-for="g in grades" :key="g" :label="g" :value="g" />
        </el-select>
      </el-form-item>

      <el-form-item>
        <div class="action-buttons">
          <el-upload
            action="/api/consumptionRecord/import"
            :headers="{ token: token }"
            :show-file-list="false"
            accept=".csv,.xls,.xlsx"
            :on-success="handleImportSuccess"
            :before-upload="beforeImportUpload"
          >
            <el-button type="success">导入消费记录</el-button>
          </el-upload>
          <el-button type="primary" @click="onSearch">查询</el-button>
          <el-button type="warning" @click="exportExcel" :loading="exporting" :disabled="exporting">导出Excel</el-button>
          <el-button type="info" @click="clearFilters">清空</el-button>
        </div>
      </el-form-item>
    </el-form>
  </div>

  <!-- 列表 -->
  <div class="container">
    <el-table
      :data="consumeList"
      border
      style="width: 100%"
    >
      <el-table-column type="index" label="序号" width="70" align="center" />
      <el-table-column prop="consumeTime" label="消费时间" width="180" align="center" sortable>
        <template #default="scope">
          <span>{{ formatTime(scope.row.consumeTime) }}</span>
        </template>
      </el-table-column>
      <el-table-column prop="userName" label="用户名" width="120" align="center" />
      <el-table-column prop="userId" label="学号 / 工号" width="140" align="center" />
      <el-table-column prop="merchantName" label="商户名称" width="180" align="center" show-overflow-tooltip />
      <el-table-column prop="merchantType" label="商户类型" width="120" align="center" />
      <el-table-column prop="amount" label="消费金额" width="140" align="center">
        <template #default="scope">
          <span :style="{ color: isLargeAmount(scope.row.amount) ? 'red' : '' }">
            {{ formatAmount(scope.row.amount) }}
          </span>
        </template>
      </el-table-column>
      <el-table-column label="异常标记" align="center">
        <template #default="scope">
          <template v-if="scope.row.isAbnormal">
            <el-tooltip :content="scope.row.abnormalReason || '异常'" placement="top">
              <el-tag type="danger">异常</el-tag>
            </el-tooltip>
          </template>
          <template v-else>
            <span>—</span>
          </template>
        </template>
      </el-table-column>
    </el-table>
  </div>

  <!-- 分页条 -->
  <div class="container">
    <el-pagination
      v-model:current-page="searchForm.page"
      v-model:page-size="searchForm.pageSize"
      :page-sizes="[5, 10, 20, 30, 50, 75, 100]"
      :background="background"
      :total="total"
      layout="sizes,total, prev, pager, next, jumper"
      @size-change="handleSizeChange"
      @current-change="handleCurrentChange"
    />
  </div>
</template>

<style scoped>
.container {
  margin-top: 15px;
  margin-bottom: 15px;
}
.search-form :deep(.el-form-item) {
  margin-right: 12px;
}
.action-buttons {
  display: inline-flex;
  align-items: center;
  gap: 10px;
}
</style>